using System;
using System.Collections.Generic;
using System.IO;
using System.Text;

namespace Rage
{
    public class BuffList : List<Buff>
    {
        public BuffList() : base() { }
        public BuffList(IEnumerable<Buff> collection) : base(collection) { }
    }

    public class Buff
    {
        #region Variables
        public string Name;
        public string Group;
        public Stats Stats = new Stats();
        private List<CharacterClass> _allowedClasses = null;
        public List<CharacterClass> AllowedClasses
        {
            get
            {
                return _allowedClasses ??
                    (_allowedClasses = new List<CharacterClass>() {
                        CharacterClass.Juggernaut,
                        CharacterClass.Marauder,
                        CharacterClass.Assassin,
                        CharacterClass.Sorcerer,
                        CharacterClass.Powertech,
                        CharacterClass.Mercenary,
                        CharacterClass.Operative,
                        CharacterClass.Sniper,
                        CharacterClass.Guardian,
                        CharacterClass.Sentinel,
                        CharacterClass.Shadow,
                        CharacterClass.Sage,
                        CharacterClass.Vanguard,
                        CharacterClass.Commando,
                        CharacterClass.Scoundrel,
                        CharacterClass.Gunslinger,
                    });
            }
            set { _allowedClasses = value; }
        }
        /*private List<Profession> _professions = null;
        public List<Profession> Professions
        {
            get
            {
                return _professions ??
                    (_professions = new List<Profession>() {
                        Profession.None,
                        Profession.Alchemy,
                        Profession.Blacksmithing,
                        Profession.Enchanting,
                        Profession.Engineering,
                        Profession.Herbalism,
                        Profession.Inscription,
                        Profession.Jewelcrafting,
                        Profession.Leatherworking,
                        Profession.Mining,
                        Profession.Skinning,
                        Profession.Tailoring,
                    });
            }
            set { _professions = value; }
        }*/
        public int SpellId = 0;
        public string SetName;
        public string Source;
        /// <summary>-1 = No class. Otherwise assign by CharacterClass Enum</summary>
        public int SourceClass = -1;
        public int SetThreshold = 0;
        public List<Buff> Improvements = new List<Buff>();
        public bool IsTargetDebuff = false;
        public bool IsCustom = false;
        private List<string> _conflictingBuffs = null;
        public List<string> ConflictingBuffs
        {
            get { return _conflictingBuffs ?? (_conflictingBuffs = new List<string>() { Group }); }
            set { _conflictingBuffs = value; }
        }
        public override string ToString() {
            string summary = Name + ": ";
            summary += Stats.ToString();
            summary = summary.TrimEnd(',', ' ', ':');
            return summary;
        }
        #endregion

        #region Events
        public static event EventHandler<EventArgs> BuffsLoaded;
        #endregion

        #region Static Functions
        public static void LoadDefaultBuffs(List<Buff> loadedBuffs, int level)
        {
            loadedBuffs = loadedBuffs ?? new List<Buff>();
            List<Buff> defaultBuffs = GetDefaultBuffs(level);
            Dictionary<string, Buff> allBuffs = new Dictionary<string, Buff>();
            foreach (Buff loadedBuff in loadedBuffs)
                if (loadedBuff.IsCustom)
                    allBuffs.Add(loadedBuff.Name, loadedBuff);
            foreach (Buff defaultBuff in defaultBuffs)
                if (!allBuffs.ContainsKey(defaultBuff.Name))
                    allBuffs.Add(defaultBuff.Name, defaultBuff);
            Buff[] allBuffArray = new Buff[allBuffs.Count];
            allBuffs.Values.CopyTo(allBuffArray, 0);
            _allBuffs = new BuffList(allBuffs.Values);
            _allBuffsByName = null;
            _allSetBonuses = null;
            _relevantBuffs = null;
            _relevantSetBonuses = null;
            CacheSetBonuses(); // cache it at the start because we don't like on demand caching with multithreading
            if (BuffsLoaded != null)
            {
                BuffsLoaded(null, EventArgs.Empty);
            }
        }

        public static Buff GetBuffByName(string name)
        {
#if RAGESERVER
            if (_allBuffs == null)
            {
                LoadDefaultBuffs(null, 85);
            }
#endif
            Buff buff;
            AllBuffsByName.TryGetValue(name, out buff);
            return buff;
        }

        public static Buff GetBuffBySpellId(int Id)
        {
#if RAGESERVER
            if (_allBuffs == null)
            {
                LoadDefaultBuffs(null, 85);
            }
#endif
            Buff buff;
            AllBuffsBySpellId.TryGetValue(Id, out buff);
            return buff;
        }

        #region Buff Relevancy to Character (Model, Professions)
        private static string _cachedModel = "";
        //private static string _cachedPriProf = "";
        //private static string _cachedSecProf = "";
        private static List<Buff> _relevantBuffs = new List<Buff>();
        public static CharacterClass cachedClass = CharacterClass.Juggernaut;
        //public static Profession cachedPriProf = Profession.None;
        //public static Profession cachedSecProf = Profession.None;
        /// <summary>Returns relevant buffs, but not filtered for professions</summary>
        public static List<Buff> RelevantBuffs {
            get {
                if (Calculations.Instance == null
                    || (_cachedModel != Calculations.Instance.ToString()
                        /*|| _cachedPriProf != cachedPriProf.ToString()
                        || _cachedSecProf != cachedSecProf.ToString()*/)
                    || _relevantBuffs == null) {
                    if (Calculations.Instance != null) {
                        _cachedModel = Calculations.Instance.ToString();
                        //_cachedPriProf = cachedPriProf.ToString();
                        //_cachedSecProf = cachedSecProf.ToString();
                        _relevantBuffs = AllBuffs.FindAll(buff => Calculations.IsBuffRelevant(buff,
                            new Character() { Class = cachedClass, /*PrimaryProfession = cachedPriProf, SecondaryProfession = cachedSecProf,*/ IsLoading = false }));
                    } else { _relevantBuffs = new List<Buff>(); }
                }
                return _relevantBuffs;
            }
        }
        #endregion

        public static void InvalidateBuffs() { _relevantBuffs = null; }

        #region Buffs that are Set Bonuses, which are handled separately from all other Buffs
        private static void CacheSetBonuses() {
            Dictionary<string, List<Buff>> listDict = new Dictionary<string, List<Buff>>();
            foreach (Buff buff in AllBuffs) 
            {
                string setName = buff.SetName;
                if (!string.IsNullOrEmpty(setName)) 
                {
                    List<Buff> setBonuses;
                    if (!listDict.TryGetValue(setName, out setBonuses))
                    {
                        setBonuses = new List<Buff>();
                        listDict[setName] = setBonuses;
                    }
                    setBonuses.Add(buff);
                }
            }
            foreach (var kvp in listDict)
            {
                setBonusesByName[kvp.Key] = kvp.Value.ToArray();
            }
        }

        private static List<Buff> _allSetBonuses = null;
        public static List<Buff> AllSetBonuses {
            get {
                if (_allSetBonuses == null) {
                    _allSetBonuses = AllBuffs.FindAll(buff => !string.IsNullOrEmpty(buff.SetName));
                }
                return _allSetBonuses;
            }
        }

        private static Dictionary<string, Buff[]> setBonusesByName = new Dictionary<string, Buff[]>();
        public static Buff[] GetSetBonuses(string setName) {
            Buff[] setBonuses;
            // if it's not cached we know we don't have any
            setBonusesByName.TryGetValue(setName, out setBonuses);
            return setBonuses;
        }

        private static List<Buff> _relevantSetBonuses = null;
        public static List<Buff> RelevantSetBonuses {
            get {
                if (Calculations.Instance == null || _cachedModel != Calculations.Instance.ToString() || _relevantSetBonuses == null) {
                    if (Calculations.Instance != null) {
                        _cachedModel = Calculations.Instance.ToString();
                        _relevantSetBonuses = AllBuffs.FindAll(buff =>
                            Calculations.HasRelevantStats(buff.GetTotalStats()) && !string.IsNullOrEmpty(buff.SetName));
                    } else { _relevantSetBonuses = new List<Buff>(); }
                }
                return _relevantSetBonuses;
            }
        }
        #endregion

        private static Dictionary<string, Buff> _allBuffsByName = null;
        private static Dictionary<string, Buff> AllBuffsByName {
            get {
                if (_allBuffsByName == null) {
                    _allBuffsByName = new Dictionary<string, Buff>();
                    //&UT&
                    // Chance for null
                    if (AllBuffs != null)
                    {
                        foreach (Buff buff in AllBuffs)
                        {
                            if (!_allBuffsByName.ContainsKey(buff.Name))
                            {
                                _allBuffsByName.Add(buff.Name, buff);
                                foreach (Buff improvement in buff.Improvements)
                                {
                                    if (!_allBuffsByName.ContainsKey(improvement.Name))
                                    {
                                        _allBuffsByName.Add(improvement.Name, improvement);
                                    }
                                }
                            }
                        }
                    }
                }
                return _allBuffsByName;
            }
        }

        private static Dictionary<int, Buff> _allBuffsBySpellId = null;
        private static Dictionary<int, Buff> AllBuffsBySpellId
        {
            get
            {
                if (_allBuffsBySpellId == null)
                {
                    _allBuffsBySpellId = new Dictionary<int, Buff>();
                    //&UT&
                    // Chance for null
                    if (AllBuffs != null)
                    {
                        foreach (Buff buff in AllBuffs)
                        {
                            if (!_allBuffsBySpellId.ContainsKey(buff.SpellId))
                            {
                                _allBuffsBySpellId.Add(buff.SpellId, buff);
                                int iter = 0;
                                foreach (Buff improvement in buff.Improvements)
                                {
                                    // TODO JOTHAY VERIFY THIS
                                    int impSpellId = improvement.SpellId != 0
                                        ? improvement.SpellId * 100
                                        : buff.SpellId * 100 + iter;
                                    if (!_allBuffsBySpellId.ContainsKey(impSpellId))
                                    {
                                        _allBuffsBySpellId.Add(impSpellId, improvement);
                                    }
                                    iter++;
                                }
                            }
                        }
                    }
                }
                return _allBuffsBySpellId;
            }
        }

        public Stats GetTotalStats()
        {
            Stats ret = this.Stats.Clone();
            foreach (Buff buff in Improvements)
                ret.Accumulate(buff.Stats);
            return ret;
        }

        private static BuffList _allBuffs = null;
        public static List<Buff> AllBuffs
        {
            get
            {
#if RAGESERVER
                if (_allBuffs == null)
                {
                    LoadDefaultBuffs(null, 85);
                }
#endif
                return _allBuffs;
            }
        }
        #endregion

        #region This generates the actual Buff List
        private static Buff AddSetBonus(int id, int tier, int thresh, string setName, CharacterClass allowedClass, Stats stats = null)
        {
            return AddSetBonus(id, tier, thresh, setName, new List<CharacterClass>() { allowedClass }, stats);
        }
        private static Buff AddSetBonus(int id, int tier, int thresh, string setName, CharacterClass allowedClass, CharacterClass allowedClass2, Stats stats = null)
        {
            return AddSetBonus(id, tier, thresh, setName, new List<CharacterClass>() { allowedClass, allowedClass2 }, stats);
        }
        private static Buff AddSetBonus(int id, int tier, int thresh, string setName, List<CharacterClass> allowedClasses, Stats stats = null)
        {
            Buff retVal = new Buff()
            {
                Name = string.Format("{0} ({3}{1}) {2} Piece Bonus", setName, tier, thresh, setName.StartsWith("Battle") ? "S" : "T"),
                Group = "Set Bonuses",
                SetName = setName,
                SetThreshold = thresh,
                ConflictingBuffs = new List<string>(new string[] { }),
                AllowedClasses = allowedClasses,
                Stats = stats ?? new Stats(),
                SpellId = id ^ tier,
            };
            return retVal;
        }
        private static Buff AddMedpac(int id, string name, Stats stats = null)
        {
            Buff retVal = new Buff()
            {
                Name = name,
                Group = "Medpacs",
                Stats = stats ?? new Stats(),
                SpellId = id,
            };
            return retVal;
        }
        private static Buff AddAdrenal(int id, string name, Stats stats = null)
        {
            Buff retVal = new Buff()
            {
                Name = name,
                Group = "Adrenals",
                Stats = stats ?? new Stats(),
                SpellId = id,
            };
            return retVal;
        }

        private static List<Buff> GetDefaultBuffs() { return GetDefaultBuffs(StatConversion.DEFAULTPLAYERLEVEL); }
        private static List<Buff> GetDefaultBuffs(int level = StatConversion.DEFAULTPLAYERLEVEL) {
            List<Buff> defaultBuffs = new List<Buff>();
            Buff buff;

            #region Buffs
            defaultBuffs.Add(new Buff { Name = "Unnatural Might", Source = "Sith Warrior", Group = "Bonus Damage & Healing %",
                Stats = { BonusDamageMultiplier = 0.05f, BonusHealingDoneMultiplier = 0.05f },
                ConflictingBuffs = { },
                SpellId = 414790,
            });
            defaultBuffs.Add(new Buff { Name = "Mark of Power", Source = "Sith Inquisitor", Group = "Bonus Primary Stat %",
                Stats = {
                    BonusStrengthMultiplier = 0.05f, BonusAimMultiplier = 0.05f, BonusWillpowerMultiplier = 0.05f, BonusCunningMultiplier = 0.05f,
                    DamageTakenReductionMultiplier = 0.10f },
                ConflictingBuffs = { },
                SpellId = 221840,
            });
            defaultBuffs.Add(new Buff { Name = "Hunter's Boon", Source = "Bounty Hunter", Group = "Bonus Endurance %",
                Stats = { BonusEnduranceMultiplier = 0.05f, },
                ConflictingBuffs = { },
                SpellId = 414752,
            });
            defaultBuffs.Add(new Buff { Name = "Coordination", Source = "Imperial Agent", Group = "Bonus Crit %",
                Stats = { BonusCritChance = 0.05f, },
                ConflictingBuffs = { },
                SpellId = 205344,
            });
            #endregion

            #region Debuffs
            defaultBuffs.Add(new Buff { Name = "Sunder Armor", Source = "Sith Warrior", Group = "Target Armor Reduction", IsTargetDebuff = true,
                Stats = { TargetArmorReduction = 0.20f },
                ConflictingBuffs = { },
            });
            #endregion

            #region Consumables
            #region Stims
            defaultBuffs.Add(new Buff() { Name = "Exotech Command Stim", Group = "Stims", Stats = { Presence = 164, }, });
            defaultBuffs.Add(new Buff() { Name = "Exotech Fortitude Stim", Group = "Stims", Stats = { Endurance = 128, DefenseRating = 52, }, });
            defaultBuffs.Add(new Buff() { Name = "Exotech Might Stim", Group = "Stims", Stats = { Strength = 128, Power = 52, }, });
            defaultBuffs.Add(new Buff() { Name = "Exotech Reflex Stim", Group = "Stims", Stats = { Aim = 128, Power = 52, }, });
            defaultBuffs.Add(new Buff() { Name = "Exotech Resolve Stim", Group = "Stims", Stats = { Willpower = 128, Power = 52, }, });
            defaultBuffs.Add(new Buff() { Name = "Exotech Skill Stim", Group = "Stims", Stats = { Cunning = 128, Power = 52, }, });
            defaultBuffs.Add(new Buff() { Name = "Rakata Command Stim", Group = "Stims", Stats = { Presence = 144, }, });
            defaultBuffs.Add(new Buff() { Name = "Rakata Fortitude Stim", Group = "Stims", Stats = { Endurance = 112, DefenseRating = 46 }, });
            defaultBuffs.Add(new Buff() { Name = "Rakata Might Stim", Group = "Stims", Stats = { Strength = 112, Power = 46, }, });
            defaultBuffs.Add(new Buff() { Name = "Rakata Reflex Stim", Group = "Stims", Stats = { Aim = 112, Power = 46, }, });
            defaultBuffs.Add(new Buff() { Name = "Rakata Resolve Stim", Group = "Stims", Stats = { Willpower = 112, Power = 46, }, });
            defaultBuffs.Add(new Buff() { Name = "Rakata Skill Stim", Group = "Stims", Stats = { Cunning = 112, Power = 46, }, });
            defaultBuffs.Add(new Buff() { Name = "Energized Command Stim", Group = "Stims", Stats = { Presence = 144, }, });
            defaultBuffs.Add(new Buff() { Name = "Energized Fortitude Stim", Group = "Stims", Stats = { Endurance = 112, DefenseRating = 46 }, });
            defaultBuffs.Add(new Buff() { Name = "Energized Might Stim", Group = "Stims", Stats = { Strength = 112, Power = 46, }, });
            defaultBuffs.Add(new Buff() { Name = "Energized Reflex Stim", Group = "Stims", Stats = { Aim = 112, Power = 46, }, });
            defaultBuffs.Add(new Buff() { Name = "Energized Resolve Stim", Group = "Stims", Stats = { Willpower = 112, Power = 46, }, });
            defaultBuffs.Add(new Buff() { Name = "Energized Skill Stim", Group = "Stims", Stats = { Cunning = 112, Power = 46, }, });
            defaultBuffs.Add(new Buff() { Name = "Hyper-Battle Command Stim", Group = "Stims", Stats = { Presence = 136, }, });
            defaultBuffs.Add(new Buff() { Name = "Hyper-Battle Fortitude Stim", Group = "Stims", Stats = { Endurance = 104, DefenseRating = 43, }, });
            defaultBuffs.Add(new Buff() { Name = "Hyper-Battle Might Stim", Group = "Stims", Stats = { Strength = 104, Power = 43, }, });
            defaultBuffs.Add(new Buff() { Name = "Hyper-Battle Reflex Stim", Group = "Stims", Stats = { Aim = 104, Power = 43, }, });
            defaultBuffs.Add(new Buff() { Name = "Hyper-Battle Resolve Stim", Group = "Stims", Stats = { Willpower = 104, Power = 43, }, });
            defaultBuffs.Add(new Buff() { Name = "Hyper-Battle Skill Stim", Group = "Stims", Stats = { Cunning = 104, Power = 43, }, });
            #endregion

            #region Medpacs
            defaultBuffs.Add(buff = AddMedpac(612023, "Rakata Medpac", new Stats()));
            buff.Stats.AddSpecialEffect(new SpecialEffect(Trigger.Use, new Stats() { HealthRestore = (3750f + 4575f) / 2f, BonusHealthMultiplier = 0.15f, }, 15f, 90f));
            defaultBuffs.Add(buff = AddMedpac(582271, "Reusable Ultimate Medpac", new Stats()));
            buff.Stats.AddSpecialEffect(new SpecialEffect(Trigger.Use, new Stats() { HealthRestore = (3750f + 4575f) / 2f, }, 15f, 90f));
            defaultBuffs.Add(buff = AddMedpac(582223, "Prototype Ultimate Medpac", new Stats()));
            buff.Stats.AddSpecialEffect(new SpecialEffect(Trigger.Use, new Stats() { HealthRestore = (3750f + 4575f) / 2f, }, 15f, 90f));
            defaultBuffs.Add(buff = AddMedpac(582270, "Reusable Advanced Medpac", new Stats()));
            buff.Stats.AddSpecialEffect(new SpecialEffect(Trigger.Use, new Stats() { HealthRestore = (3475f + 4250f) / 2f, }, 15f, 90f));
            defaultBuffs.Add(buff = AddMedpac(339820, "Ultimate Medpac", new Stats()));
            buff.Stats.AddSpecialEffect(new SpecialEffect(Trigger.Use, new Stats() { HealthRestore = (3750f + 4575f) / 2f, }, 15f, 90f));
            defaultBuffs.Add(buff = AddMedpac(196243, "Exceptional Medpac", new Stats()));
            buff.Stats.AddSpecialEffect(new SpecialEffect(Trigger.Use, new Stats() { HealthRestore = (3000f + 3675f) / 2f, }, 15f, 90f));
            defaultBuffs.Add(buff = AddMedpac(582222, "Prototype Advanced Medpac", new Stats()));
            buff.Stats.AddSpecialEffect(new SpecialEffect(Trigger.Use, new Stats() { HealthRestore = (3475f + 4250f) / 2f, Health = 1545f, }, 15f, 90f));
            #endregion

            #region Adrenals
            defaultBuffs.Add(buff = AddAdrenal(612014, "Rakata Triage Adrenal", new Stats())); buff.Stats.AddSpecialEffect(new SpecialEffect(Trigger.Use, new Stats() { ForcePower = 565f, TechPower = 565f, BonusDamageMultiplier = -0.50f, }, 15f, 180f));
            defaultBuffs.Add(buff = AddAdrenal(612016, "Rakata Tech Adrenal", new Stats())); buff.Stats.AddSpecialEffect(new SpecialEffect(Trigger.Use, new Stats() { AccuracyRating = 565f, }, 15f, 180f));
            defaultBuffs.Add(buff = AddAdrenal(612013, "Rakata Force Adrenal",    new Stats())); buff.Stats.AddSpecialEffect(new SpecialEffect(Trigger.Use, new Stats() { SurgeRating = 565f, }, 15f, 180f));
            defaultBuffs.Add(buff = AddAdrenal(612011, "Rakata Efficacy Adrenal", new Stats())); buff.Stats.AddSpecialEffect(new SpecialEffect(Trigger.Use, new Stats() { AlacrityRating = 565f, }, 15f, 180f));
            defaultBuffs.Add(buff = AddAdrenal(612012, "Rakata Critical Adrenal", new Stats())); buff.Stats.AddSpecialEffect(new SpecialEffect(Trigger.Use, new Stats() { CritRating = 565f, }, 15f, 180f));
            defaultBuffs.Add(buff = AddAdrenal(612010, "Rakata Attack Adrenal",   new Stats())); buff.Stats.AddSpecialEffect(new SpecialEffect(Trigger.Use, new Stats() { Power = 565f, }, 15f, 180f));
            defaultBuffs.Add(buff = AddAdrenal(612015, "Rakata Absorb Adrenal",   new Stats())); buff.Stats.AddSpecialEffect(new SpecialEffect(Trigger.Use, new Stats() { Armor = 1725f, }, 15f, 180f));
            defaultBuffs.Add(buff = AddAdrenal(612000, "Exotech Triage Adrenal", new Stats())); buff.Stats.AddSpecialEffect(new SpecialEffect(Trigger.Use, new Stats() { ForcePower = 535f, TechPower = 535f, BonusDamageMultiplier = -0.50f, }, 15f, 180f));
            defaultBuffs.Add(buff = AddAdrenal(612002, "Exotech Tech Adrenal", new Stats())); buff.Stats.AddSpecialEffect(new SpecialEffect(Trigger.Use, new Stats() { AccuracyRating = 535f, }, 15f, 180f));
            defaultBuffs.Add(buff = AddAdrenal(611999, "Exotech Force Adrenal", new Stats())); buff.Stats.AddSpecialEffect(new SpecialEffect(Trigger.Use, new Stats() { SurgeRating = 535f, }, 15f, 180f));
            defaultBuffs.Add(buff = AddAdrenal(611997, "Exotech Efficacy Adrenal", new Stats())); buff.Stats.AddSpecialEffect(new SpecialEffect(Trigger.Use, new Stats() { AlacrityRating = 535f, }, 15f, 180f));
            defaultBuffs.Add(buff = AddAdrenal(611998, "Exotech Critical Adrenal", new Stats())); buff.Stats.AddSpecialEffect(new SpecialEffect(Trigger.Use, new Stats() { CritRating = 535f, }, 15f, 180f));
            defaultBuffs.Add(buff = AddAdrenal(611996, "Exotech Attack Adrenal", new Stats())); buff.Stats.AddSpecialEffect(new SpecialEffect(Trigger.Use, new Stats() { Power = 535f, }, 15f, 180f));
            defaultBuffs.Add(buff = AddAdrenal(612001, "Exotech Absorb Adrenal", new Stats())); buff.Stats.AddSpecialEffect(new SpecialEffect(Trigger.Use, new Stats() { Armor = 1675f, }, 15f, 180f));
            defaultBuffs.Add(buff = AddAdrenal(582187, "Reusable Hyper-Battle Triage Adrenal", new Stats())); buff.Stats.AddSpecialEffect(new SpecialEffect(Trigger.Use, new Stats() { ForcePower = 450f, TechPower = 450f, BonusDamageMultiplier = -0.50f, }, 15f, 180f));
            defaultBuffs.Add(buff = AddAdrenal(582199, "Reusable Hyper-Battle Tech Adrenal", new Stats())); buff.Stats.AddSpecialEffect(new SpecialEffect(Trigger.Use, new Stats() { AccuracyRating = 450f, }, 15f, 180f));
            defaultBuffs.Add(buff = AddAdrenal(582205, "Reusable Hyper-Battle Force Adrenal", new Stats())); buff.Stats.AddSpecialEffect(new SpecialEffect(Trigger.Use, new Stats() { SurgeRating = 450f, }, 15f, 180f));
            defaultBuffs.Add(buff = AddAdrenal(582217, "Reusable Hyper-Battle Efficacy Adrenal", new Stats())); buff.Stats.AddSpecialEffect(new SpecialEffect(Trigger.Use, new Stats() { AlacrityRating = 450f, }, 15f, 180f));
            defaultBuffs.Add(buff = AddAdrenal(582211, "Reusable Hyper-Battle Critical Adrenal", new Stats())); buff.Stats.AddSpecialEffect(new SpecialEffect(Trigger.Use, new Stats() { CritRating = 450f, }, 15f, 180f));
            defaultBuffs.Add(buff = AddAdrenal(582193, "Reusable Hyper-Battle Attack Adrenal", new Stats())); buff.Stats.AddSpecialEffect(new SpecialEffect(Trigger.Use, new Stats() { Power = 450f, }, 15f, 180f));
            defaultBuffs.Add(buff = AddAdrenal(582181, "Reusable Hyper-Battle Absorb Adrenal", new Stats())); buff.Stats.AddSpecialEffect(new SpecialEffect(Trigger.Use, new Stats() { Armor = 1500f, }, 15f, 180f));
            defaultBuffs.Add(buff = AddAdrenal(611986, "Energized Triage Adrenal", new Stats())); buff.Stats.AddSpecialEffect(new SpecialEffect(Trigger.Use, new Stats() { ForcePower = 475f, TechPower = 475f, BonusDamageMultiplier = -0.50f, }, 15f, 180f));
            defaultBuffs.Add(buff = AddAdrenal(611988, "Energized Tech Adrenal", new Stats())); buff.Stats.AddSpecialEffect(new SpecialEffect(Trigger.Use, new Stats() { AccuracyRating = 475f, }, 15f, 180f));
            defaultBuffs.Add(buff = AddAdrenal(611985, "Energized Force Adrenal", new Stats())); buff.Stats.AddSpecialEffect(new SpecialEffect(Trigger.Use, new Stats() { SurgeRating = 475f, }, 15f, 180f));
            defaultBuffs.Add(buff = AddAdrenal(611983, "Energized Efficacy Adrenal", new Stats())); buff.Stats.AddSpecialEffect(new SpecialEffect(Trigger.Use, new Stats() { AlacrityRating = 475f, }, 15f, 180f));
            defaultBuffs.Add(buff = AddAdrenal(611984, "Energized Critical Adrenal", new Stats())); buff.Stats.AddSpecialEffect(new SpecialEffect(Trigger.Use, new Stats() { CritRating = 475f, }, 15f, 180f));
            defaultBuffs.Add(buff = AddAdrenal(611982, "Energized Attack Adrenal", new Stats())); buff.Stats.AddSpecialEffect(new SpecialEffect(Trigger.Use, new Stats() { Power = 475f, }, 15f, 180f));
            defaultBuffs.Add(buff = AddAdrenal(611987, "Energized Absorb Adrenal", new Stats())); buff.Stats.AddSpecialEffect(new SpecialEffect(Trigger.Use, new Stats() { Armor = 1575f, }, 15f, 180f));
            defaultBuffs.Add(buff = AddAdrenal(338405, "Hyper-Battle Triage Adrenal", new Stats())); buff.Stats.AddSpecialEffect(new SpecialEffect(Trigger.Use, new Stats() { ForcePower = 450f, TechPower = 450f, BonusDamageMultiplier = -0.50f, }, 15f, 180f));
            defaultBuffs.Add(buff = AddAdrenal(338417, "Hyper-Battle Tech Adrenal", new Stats())); buff.Stats.AddSpecialEffect(new SpecialEffect(Trigger.Use, new Stats() { AccuracyRating = 450f, }, 15f, 180f));
            defaultBuffs.Add(buff = AddAdrenal(338423, "Hyper-Battle Force Adrenal", new Stats())); buff.Stats.AddSpecialEffect(new SpecialEffect(Trigger.Use, new Stats() { SurgeRating = 450f, }, 15f, 180f));
            defaultBuffs.Add(buff = AddAdrenal(338435, "Hyper-Battle Efficacy Adrenal", new Stats())); buff.Stats.AddSpecialEffect(new SpecialEffect(Trigger.Use, new Stats() { AlacrityRating = 450f, }, 15f, 180f));
            defaultBuffs.Add(buff = AddAdrenal(338429, "Hyper-Battle Critical Adrenal", new Stats())); buff.Stats.AddSpecialEffect(new SpecialEffect(Trigger.Use, new Stats() { CritRating = 450f, }, 15f, 180f));
            defaultBuffs.Add(buff = AddAdrenal(338411, "Hyper-Battle Attack Adrenal", new Stats())); buff.Stats.AddSpecialEffect(new SpecialEffect(Trigger.Use, new Stats() { Power = 450f, }, 15f, 180f));
            defaultBuffs.Add(buff = AddAdrenal(338399, "Hyper-Battle Absorb Adrenal", new Stats())); buff.Stats.AddSpecialEffect(new SpecialEffect(Trigger.Use, new Stats() { Armor = 1500f, }, 15f, 180f));
            #endregion
            #endregion

            #region Set Bonuses
            defaultBuffs.Add(AddSetBonus(59, 1, 2, "Battlemaster Combat Medic's Gear", CharacterClass.Mercenary, CharacterClass.Powertech));
            defaultBuffs.Add(AddSetBonus(59, 1, 4, "Battlemaster Combat Medic's Gear", CharacterClass.Mercenary, CharacterClass.Powertech));
            defaultBuffs.Add(AddSetBonus(57, 1, 2, "Battlemaster Combat Tech's Gear", CharacterClass.Mercenary, CharacterClass.Powertech));
            defaultBuffs.Add(AddSetBonus(57, 1, 4, "Battlemaster Combat Tech's Gear", CharacterClass.Mercenary, CharacterClass.Powertech));
            defaultBuffs.Add(AddSetBonus(55, 1, 2, "Battlemaster Eliminator's Gear", CharacterClass.Mercenary));
            defaultBuffs.Add(AddSetBonus(55, 1, 4, "Battlemaster Eliminator's Gear", CharacterClass.Mercenary));
            defaultBuffs.Add(AddSetBonus(58, 1, 2, "Battlemaster Enforcer's Gear", CharacterClass.Operative));
            defaultBuffs.Add(AddSetBonus(58, 1, 4, "Battlemaster Enforcer's Gear", CharacterClass.Operative));
            defaultBuffs.Add(AddSetBonus(60, 1, 2, "Battlemaster Field Medic's Gear", CharacterClass.Operative));
            defaultBuffs.Add(AddSetBonus(60, 1, 4, "Battlemaster Field Medic's Gear", CharacterClass.Operative));
            defaultBuffs.Add(AddSetBonus(56, 1, 2, "Battlemaster Field Tech's Gear", CharacterClass.Operative));
            defaultBuffs.Add(AddSetBonus(56, 1, 4, "Battlemaster Field Tech's Gear", CharacterClass.Operative));
            defaultBuffs.Add(AddSetBonus(48, 1, 2, "Battlemaster Force-Master's Gear", CharacterClass.Assassin, CharacterClass.Sorcerer));
            defaultBuffs.Add(AddSetBonus(48, 1, 4, "Battlemaster Force-Master's Gear", CharacterClass.Assassin, CharacterClass.Sorcerer));
            defaultBuffs.Add(AddSetBonus(49, 1, 2, "Battlemaster Force-Mystic's Gear", CharacterClass.Assassin, CharacterClass.Sorcerer));
            defaultBuffs.Add(AddSetBonus(49, 1, 4, "Battlemaster Force-Mystic's Gear", CharacterClass.Assassin, CharacterClass.Sorcerer));
            defaultBuffs.Add(AddSetBonus(50, 1, 2, "Battlemaster Stalker's Gear", CharacterClass.Assassin, CharacterClass.Sorcerer));
            defaultBuffs.Add(AddSetBonus(50, 1, 4, "Battlemaster Stalker's Gear", CharacterClass.Assassin, CharacterClass.Sorcerer));
            defaultBuffs.Add(AddSetBonus(61, 1, 2, "Battlemaster Supercommando's Gear", CharacterClass.Powertech));
            defaultBuffs.Add(AddSetBonus(61, 1, 4, "Battlemaster Supercommando's Gear", CharacterClass.Powertech));
            defaultBuffs.Add(AddSetBonus(51, 1, 2, "Battlemaster Survivor's Gear", CharacterClass.Assassin));
            defaultBuffs.Add(AddSetBonus(51, 1, 4, "Battlemaster Survivor's Gear", CharacterClass.Assassin));
            defaultBuffs.Add(AddSetBonus(52, 1, 2, "Battlemaster Vindicator's Gear", CharacterClass.Juggernaut));
            defaultBuffs.Add(AddSetBonus(52, 1, 4, "Battlemaster Vindicator's Gear", CharacterClass.Juggernaut));
            defaultBuffs.Add(AddSetBonus(54, 1, 2, "Battlemaster War Leader's Gear", CharacterClass.Juggernaut));
            defaultBuffs.Add(AddSetBonus(54, 1, 4, "Battlemaster War Leader's Gear", CharacterClass.Juggernaut));
            defaultBuffs.Add(AddSetBonus(53, 1, 2, "Battlemaster Weaponmaster's Gear", CharacterClass.Marauder));
            defaultBuffs.Add(AddSetBonus(53, 1, 4, "Battlemaster Weaponmaster's Gear", CharacterClass.Marauder));
            defaultBuffs.Add(AddSetBonus(45, 1, 2, "Rakata Combat Medic's Gear", CharacterClass.Mercenary, CharacterClass.Powertech));
            defaultBuffs.Add(AddSetBonus(45, 1, 4, "Rakata Combat Medic's Gear", CharacterClass.Mercenary, CharacterClass.Powertech));
            defaultBuffs.Add(AddSetBonus(43, 1, 2, "Rakata Combat Tech's Gear", CharacterClass.Mercenary, CharacterClass.Powertech));
            defaultBuffs.Add(AddSetBonus(43, 1, 4, "Rakata Combat Tech's Gear", CharacterClass.Mercenary, CharacterClass.Powertech));
            defaultBuffs.Add(AddSetBonus(41, 1, 2, "Rakata Eliminator's Gear", CharacterClass.Mercenary));
            defaultBuffs.Add(AddSetBonus(41, 1, 4, "Rakata Eliminator's Gear", CharacterClass.Mercenary));
            defaultBuffs.Add(AddSetBonus(44, 1, 2, "Rakata Enforcer's Gear", CharacterClass.Operative));
            defaultBuffs.Add(AddSetBonus(44, 1, 4, "Rakata Enforcer's Gear", CharacterClass.Operative));
            defaultBuffs.Add(AddSetBonus(46, 1, 2, "Rakata Field Medic's Gear", CharacterClass.Operative));
            defaultBuffs.Add(AddSetBonus(46, 1, 4, "Rakata Field Medic's Gear", CharacterClass.Operative));
            defaultBuffs.Add(AddSetBonus(42, 1, 2, "Rakata Field Tech's Gear", CharacterClass.Operative));
            defaultBuffs.Add(AddSetBonus(42, 1, 4, "Rakata Field Tech's Gear", CharacterClass.Operative));
            defaultBuffs.Add(AddSetBonus(43, 1, 2, "Rakata Force-Master's Gear", CharacterClass.Assassin, CharacterClass.Sorcerer));
            defaultBuffs.Add(AddSetBonus(34, 1, 4, "Rakata Force-Master's Gear", CharacterClass.Assassin, CharacterClass.Sorcerer));
            defaultBuffs.Add(AddSetBonus(35, 1, 2, "Rakata Force-Mystic's Gear", CharacterClass.Assassin, CharacterClass.Sorcerer));
            defaultBuffs.Add(AddSetBonus(35, 1, 4, "Rakata Force-Mystic's Gear", CharacterClass.Assassin, CharacterClass.Sorcerer));
            defaultBuffs.Add(AddSetBonus(36, 1, 2, "Rakata Stalker's Gear", CharacterClass.Assassin, CharacterClass.Sorcerer));
            defaultBuffs.Add(AddSetBonus(36, 1, 4, "Rakata Stalker's Gear", CharacterClass.Assassin, CharacterClass.Sorcerer));
            defaultBuffs.Add(AddSetBonus(47, 1, 2, "Rakata Supercommando's Gear", CharacterClass.Powertech));
            defaultBuffs.Add(AddSetBonus(47, 1, 4, "Rakata Supercommando's Gear", CharacterClass.Powertech));
            defaultBuffs.Add(AddSetBonus(37, 1, 2, "Rakata Survivor's Gear", CharacterClass.Assassin));
            defaultBuffs.Add(AddSetBonus(37, 1, 4, "Rakata Survivor's Gear", CharacterClass.Assassin));
            defaultBuffs.Add(AddSetBonus(38, 1, 2, "Rakata Vindicator's Gear", CharacterClass.Juggernaut));
            defaultBuffs.Add(AddSetBonus(38, 1, 4, "Rakata Vindicator's Gear", CharacterClass.Juggernaut));
            defaultBuffs.Add(AddSetBonus(40, 1, 2, "Rakata War Leader's Gear", CharacterClass.Juggernaut));
            defaultBuffs.Add(AddSetBonus(40, 1, 4, "Rakata War Leader's Gear", CharacterClass.Juggernaut));
            defaultBuffs.Add(AddSetBonus(39, 1, 2, "Rakata Weaponmaster's Gear", CharacterClass.Marauder));
            defaultBuffs.Add(AddSetBonus(39, 1, 4, "Rakata Weaponmaster's Gear", CharacterClass.Marauder));
            #endregion

            return defaultBuffs;
        }
        #endregion
    }
}
